package com.simple.util.base.extend;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @program: simple_tools
 * @description: 集合工具类
 * @author: ChenWenLong
 * @create: 2019-10-17 15:17
 **/
public class CollectionUtil {

    /**
     * 功能描述:
     * 〈根据指定数量分割数组〉
     *
     * @return : java.util.List<java.util.List<T>>
     * @params : [list, groupSize]
     * @author : cwl
     * @date : 2019/7/29 20:02
     */
    public static <T> List<List<T>> splitList(List<T> list, int groupSize) {
        int length = list.size();
        // 计算可以分成多少组
        int num = (length + groupSize - 1) / groupSize;
        List<List<T>> newList = new ArrayList<>(num);
        for (int i = 0; i < num; i++) {
            // 开始位置
            int fromIndex = i * groupSize;
            // 结束位置
            int toIndex = (i + 1) * groupSize < length ? (i + 1) * groupSize : length;
            newList.add(list.subList(fromIndex, toIndex));
        }
        return newList;
    }

    /**
     * 功能描述:
     * 〈获取笛卡尔积〉
     *
     * @return : void
     * @params : [sourceData, targetData, level, appendData]
     * @author : cwl
     * @date : 2019/7/10 16:24
     */
    public static <T> void recursionGenerateSku(List<List<T>> sourceData,
                                                List<List<T>> targetData,
                                                int level,
                                                List<T> appendData) {
        if (level < sourceData.size() - 1) {
            List<T> innerSkuPropertyValueList = sourceData.get(level);
            for (T spv : innerSkuPropertyValueList) {
                List<T> innerAppendData = new ArrayList<>(appendData);
                innerAppendData.add(spv);
                recursionGenerateSku(sourceData, targetData, level + 1, innerAppendData);
            }
        } else {
            List<T> innerSkuPropertyValueList = sourceData.get(level);
            for (T spv : innerSkuPropertyValueList) {
                List<T> innerAppendData = new ArrayList<>(appendData);
                innerAppendData.add(spv);
                targetData.add(innerAppendData);
            }
        }
    }

    /**
     * 功能描述:
     * (转换成Map嵌套List的集合〉
     *
     * @return : java.util.Map<java.lang.String,java.util.List<T>>
     * @params : [srcList, fieldName]
     * @author : cwl
     * @date : 2019/7/8 15:18
     */
    public static <T> Map<String, List<T>> toMap(List<T> srcList, String fieldName) throws Exception {
        Map<String, List<T>> resultMap = new HashMap<>();
        for (T src : srcList) {
            String key = getToMapField(src, fieldName);
            List<T> list = resultMap.get(key);
            if (list == null) {
                list = new ArrayList<>();
            }
            list.add(src);
            resultMap.put(key, list);
        }
        return resultMap;
    }

    /**
     * 功能描述:
     * 〈根据字段名称获取〉
     *
     * @return : java.lang.String
     * @params : [fieldName]
     * @author : cwl
     * @date : 2019/7/8 15:21
     */
    private static String getToMapField(Object src, String fieldName) throws NoSuchFieldException, IllegalAccessException {
        Class<?> srcClass = src.getClass();
        Field declaredField = srcClass.getDeclaredField(fieldName);
        declaredField.setAccessible(true);
        return declaredField.get(src).toString();
    }

    /**
     * 功能描述:
     * 〈根据字节码destClass拷贝属性,ignoreFields为忽略拷贝的字段〉
     *
     * @return : java.util.List<T>
     * @params : [srcList, destClass, ignoreFields]
     * @author : cwl
     * @date : 2019/7/8 13:40
     */
    public static <T> List<T> copy(List<? extends Object> srcList, Class<T> destClass, String... ignoreFields) throws Exception {
        List<T> resultList = new ArrayList<>();
        for (Object src : srcList) {
            T t = destClass.newInstance();
            //TODO 拷贝方法自行引入Common.lang3工具包或其它工具包
            //BeanUtils.copyProperties(src,t,ignoreFields);
            resultList.add(t);
        }
        return resultList;
    }

    /**
     * 功能描述:
     * 〈根据字节码destClass拷贝属性〉
     *
     * @return : java.util.List<T>
     * @params : [srcList, destClass]
     * @author : cwl
     * @date : 2019/7/8 13:41
     */
    public static <T> List<T> copy(List<? extends Object> srcList, Class<T> destClass) throws Exception {
        return copy(srcList, destClass, null);
    }
}

